<?php
/*
 * 自动验证的完成类
 * */
header("Content-type: text/html; charset=utf-8");
class Model{
    private $validate;          //用户定义的自动验证的规则
    private $auto;              //用户定义的自动完成的规则
    private $model;             //用户定义的model类       可能里面有用户定义的验证方法
    /*
     * 构造函数
     * $name    model中文件的名称  格式:nameModel.class.php
     *          格式的处理位于DB.class.php的check()方法中
     * */
    public function __construct($name){
        if(file_exists(__ROOT__."/". $GLOBALS["ps"]["appname"]."/model/".$name.".class.php")) {
            require_once __ROOT__ . "/" . $GLOBALS["ps"]["appname"] . "/model/" . $name.".class.php";
            $this->model = new $name();
            if(isset($this->model->validate) && is_array($this->model->validate)) {
                $this->validate = $this->model->validate;         //获取用户定义的规则
            } else{
                $this->validate = array();
            }
            if(isset($this->model->auto) && is_array($this->model->auto)){
                $this->auto = $this->model->auto;
            } else{
                $this->auto = array();
            }
        } else{
            die("<h2>自动严重的模板文件并不存在,请创建".$name."文件</h2>");
        }
        unset($name);           //释放无用资源
    }

    /*
     * 自动验证
     * 会自动配合用户定义的验证规则来完成自动验证的
     * 参数:
     * $data  要传入一个验证的数组(键值数组)   默认是空数组
     * $rule  验证的条件1,2,3,4,5,6,7,...... 默认是1
     * 返回一个键值数组
     * ispass   验证是否通过 true通过  false不通过
     * message  验证返回的错误信息 通过则是空  不通过则是用户定下的错误信息
     * */
    public function check(&$data=array(),$rule=1){
        //自动验证数据正确性
        $vali_len = count($this->validate);             //获取验证的数组大小
        for($i=0;$i<$vali_len;$i++){
            if($this->validate[$i][5] == 3){
                $this->validate[$i][5] = array(1,2);
            } else{
                $this->validate[$i][5] = array($this->validate[$i][5]);
            }
            if(count($this->validate[$i]) == 6  && in_array($rule,$this->validate[$i][5])){            //匹配验证的条件
                $methor = strtolower($this->validate[$i][3]);             //验证的方法
                $field_name = explode(",",$this->validate[$i][0]);
                $field_num = count($field_name);                 //获取字段的个数
                $field_value = array();
                if($this->validate[$i][4] != 1){                    //如果是存在验证
                    if($field_num > 1) {
                        $isnext = false;
                        for ($j = 0; $j < $field_num; $j++) {
                            if(!isset($data[$field_name[$j]]) || empty($data[$field_name[$j]])){             //多个字段就判段是否每个字段都存在
                                $isnext = true;
                                break;
                            }
                        }
                        if($isnext){
                            continue;               //如果有字段不存在就舍弃下面的操作
                        }
                    } else{
                        if(!isset($data[$this->validate[$i][0]]) || empty($data[$this->validate[$i][0]])){    //如果有字段不存在就舍弃下面的操作
                            continue;
                        }
                    }
                }
                if($field_num > 1) {
                    for ($j = 0; $j < $field_num; $j++) {
                        if(isset($data[$field_name[$j]])) {
                            $field_value[$field_name[$j]] = $data[$field_name[$j]];
                        }else{
                            $result["ispass"] = false;
                            $result["message"] = $this->validate[$i][2];                //保存错误信息
                            return $result;
                        }
                    }
                }else{
                    if(isset($data[$this->validate[$i][0]])) {
                        $field_value = $data[$this->validate[$i][0]];
                    } else{
                        $result["ispass"] = false;
                        $result["message"] = $this->validate[$i][2];                //保存错误信息
                        return $result;
                    }
                }
                if(!$this->$methor($this->validate[$i][1],$field_value)){      //一旦错误就马上return 返回
                    $result["ispass"] = false;
                    $result["message"] = $this->validate[$i][2];                //保存错误信息
                    return $result;
                }
            }
            unset($methor,$field_name,$field_num,$field_value);     //释放无用资源
        }
        unset($vali_len);           //释放无用资源
        //自动完成填充(在验证全部通过的前提下才会填充数据)
        $auto_len = count($this->auto);
        for($i = 0;$i < $auto_len;$i++){
            if($this->auto[$i][3] == 3){
                $this->auto[$i][3] = array(1,2);
            } else{
                $this->auto[$i][3] = array($this->auto[$i][3]);
            }
            if(count($this->auto[$i]) == 4  && in_array($rule,$this->auto[$i][3])) {            //匹配填充的条件
                $methor = strtolower($this->auto[$i][1]);             //填充的方法
                $data[$this->auto[$i][0]] = !isset($data[$this->auto[$i][0]])? "" : $data[$this->auto[$i][0]];
                $data[$this->auto[$i][0]] = $this->$methor($this->auto[$i][2],$data[$this->auto[$i][0]]);
            }
            unset($methor);     //释放无用资源
        }
        unset($auto_len);           //释放无用资源
        $result["ispass"] = true;           //所有验证都通过true
        $result["message"] = "";            //错误信息为空
        return $result;
    }

    /*
     * regex验证
     * 只能验证require必须 number是否是正整数 url地址  email邮箱
     * 参数:
     * $data    需要验证的数据     默认空
     * $rule    需要验证规则      默认空
     * 返回true或false
     * */
    private function regex($rule="",$data=""){
        $rule = strtolower($rule);
        if($rule == "require" && isset($data) && strlen($data) > 0){            //必要有.不能为空
            return true;
        }else if($rule == "number" && ctype_digit($data)){      //正整数的验证
            return true;
        }else if($rule == "url" && filter_var($data,FILTER_VALIDATE_URL)){      //url地址的合法验证
            return true;
        }else if($rule == "email" && filter_var($data,FILTER_VALIDATE_EMAIL)){      //邮箱的合法验证
            return true;
        }
        return false;
    }

    /*
     * in验证
     * 验证一个数据是否在指定的数组中
     * 参数
     * $arr     指定的数组数据     默认是空数组
     * $data    验证的数据         默认是空
     * 返回true或false
     * */
    private function in($arr=array(),$data=""){
        if(in_array($data,$arr)){               //检测数据是否在指定数组中
            return true;
        }
        return false;
    }

    /*
     * notin验证
     * 验证一个数据是否在指定的数组中
     * 参数
     * $arr     指定的数组数据     默认是空数组
     * $data    验证的数据         默认是空
     * 返回true或false
     * */
    private function notin($arr=array(),$data=""){
        if(!in_array($data,$arr)){               //检测数据是否在指定数组中
            return true;
        }
        return false;
    }

    /*
     * length验证
     * 长度的验证,针对与字符串...主要是utf-8格式字串的验证
     * 参数:
     * $len  数组(索引数组) 元素1是最小长度  元素2是最大长度    默认空
     * $data 验证的字串   默认空
     * 返回true或false
     * */
    private function length($len=array(0,0),$data=""){
        $data_len = strlen($data);
        if($data_len >= $len[0] && $data_len <= $len[1]){
            return true;
        }
        return false;
    }

    /*
     * equal验证
     * 验证数据是否等于规定的数据(数值上的相等)
     * 参数
     * $str  规定的数据 字串 默认空
     * $data 验证的数据 字串 默认空
     * 返回true或false
     * */
    private function equal($str="",$data=""){
        if($str == $data){
            return true;
        }
        return false;
    }

    /*
     * notequal验证
     * 验证数据是否不等于规定的数据(数值上的相等)
     * 参数
     * $str  规定的数据 字串 默认空
     * $data 验证的数据 字串 默认空
     * 返回true或false
     * */
    private function notequal($str="",$data=""){
        if($str != $data){
            return true;
        }
        return false;
    }

    /*
     * between验证
     * 验证一个数字是否在指定范围中
     * $arr   指定的范围 数组(索引数组) 元素1是最小  元素2是最大
     * $data  指定的数字
     * 返回true或false
     * */
    private function between($arr=array(0,0),$data=0){
        if($data >= $arr[0] && $data <= $arr[1]){
            return true;
        }
        return false;
    }

    /*
     * notbetween验证
     * 验证一个数字是否在指定范围中
     * $arr   指定的范围 数组(索引数组) 元素1是最小  元素2是最大
     * $data  指定的数字
     * 返回true或false
     * */
    private function notbetween($arr=array(0,0),$data=0){
        if($data <= $arr[0] || $data >= $arr[1]){
            return true;
        }
        return false;
    }

    /*
     * callback验证
     * 使用用户自定义的方法进行验证
     * 参数:
     * $methor      用户自定义的方法名称  默认空
     * $data        需要验证的数据 默认空 可以是数组
     * */
    private function callback($methor="",$data=""){
        return $this->model->$methor($data);
    }

    /*
     * 自动填充时间
     * */
    private function time(){
        return time();
    }

    /*
     * 自动填充字符串(也可以是数据)
     * $data  表示填充的数据
     * */
    private function fill($data=""){
        return $data;
    }

    /*
     * 自动截取字符串长度
     * $len   表示截取的长度
     * $data  截取的字段原数据
     * */
    private function cut($len=0,$data=""){
        return substr($data,0,$len);
    }

    /*
     * 自动md5加密
     * */
    private function md5($arr3,$data){
        return md5($data);
    }

    /*
     * 自动调用回调函数
     * $methor  方法名称
     * */
    private function methor($methor=""){
        return $this->model->$methor();
    }

}